package com.zts.modules.sys.controller;

import com.zts.base.BasicResourceAssembler;
import com.zts.base.exception.InvalidArgumentException;
import com.zts.base.page.PageBound;
import com.zts.base.resource.ListResource;
import com.zts.modules.sys.entity.Resource;
import com.zts.modules.sys.entity.Role;
import com.zts.modules.sys.entity.User;
import com.zts.modules.sys.entity.model.RoleModel;
import com.zts.modules.sys.entity.resource.ResourceResource;
import com.zts.modules.sys.entity.resource.RoleResource;
import com.zts.modules.sys.entity.resource.UserResource;
import com.zts.modules.sys.mapper.RoleMapper;
import com.zts.modules.sys.service.ResourceService;
import com.zts.modules.sys.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.ExposesResourceFor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.method.P;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Created by lily on 2017/6/13.
 */
@RestController("roleController")
@RequestMapping("/v1/roles")
@Api(value = "roles", description = "角色相关API")
@ExposesResourceFor(RoleResource.class)
public class RoleController {
    private static Logger logger = LoggerFactory.getLogger(RoleController.class);
    @Autowired
    RoleService roleService;

    @Autowired
    ResourceService resourceService;

    private BasicResourceAssembler<Role, RoleResource> roleAssembler =
            new BasicResourceAssembler<>(RoleController.class, RoleResource.class);

    private BasicResourceAssembler<User, UserResource> userAssembler =
            new BasicResourceAssembler<>(RoleController.class, UserResource.class);

    private BasicResourceAssembler<Resource, ResourceResource> resourceAssembler =
            new BasicResourceAssembler<>(RoleController.class, ResourceResource.class);
    //===================================角色的增删改查 begin====================================================

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "getRoles", httpMethod = "GET", value = "获取角色的分页信息")
    public final ListResource<RoleResource> getGroups(@ApiParam(required = false, value = "角色的查询条件")
                                                      @ModelAttribute("roleModel") RoleModel roleModel,
                                                      PageBound pageBound) {
        List<Role> list = roleService.getList(roleModel.transEntity(), pageBound);
        return roleAssembler.toListResource(list);
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{id}", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "getRole", httpMethod = "GET", value = "根据主键id查询角色")
    public final RoleResource getRole(@ApiParam(required = true, value = "角色的主键id")
                                      @PathVariable("id") Long id) {
        return roleAssembler.toResource(roleService.get(id));
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "", method = RequestMethod.POST,
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE,
                    MediaType.APPLICATION_JSON_VALUE},
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "addRole", httpMethod = "POST", value = "新增角色")
    public final RoleResource insertRole(@ApiParam(value = "角色信息，传送格式为JSON")
                                         @RequestBody RoleModel roleModel) {

        Role role = roleService.insert(roleModel.transEntity());
        return roleAssembler.toResource(role);
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT,
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE,
                    MediaType.APPLICATION_JSON_VALUE},
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "updateRoleById", httpMethod = "PUT", value = "根据角色的主键id更新角色")
    public final int updateRole(@ApiParam(value = "角色的主键id", required = true)
                                @PathVariable("id") Long id,
                                @ApiParam(value = "要修改的角色信息项及对应修改的值，接收数据格式为json", required = true)
                                @RequestBody RoleModel roleModel) {
        roleModel.setId(id);
        return roleService.update(roleModel.transEntity());
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "deleteRoleById", httpMethod = "DELETE", value = "根据角色的主键id删除角色")
    public final int deleteRole(@ApiParam(value = "角色的主键id", required = true)
                                @PathVariable("id") Long id) {
        Role role = new Role();
        role.setId(id);
        return roleService.delete(role);
    }
    //========================================角色的增删改查 end============================================

    //========================================角色与用户 begin============================================
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{id}/users", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "getDirectUsersOfRole", httpMethod = "GET", value = "查询拥有当前角色的直接用户")
    public final ListResource<UserResource> getUsers(@ApiParam(value = "角色的主键id", required = true)
                                                     @PathVariable("id") Long id) {
        return userAssembler.toListResource(roleService.getUsers(id));
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{id}/allusers", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "getAllUsersOfRole", httpMethod = "GET", value = "查询拥有当前角色的所有用户，包括递归下级组的用户")
    public final ListResource<UserResource> getAllUsers(@ApiParam(value = "角色的主键id", required = true)
                                                        @PathVariable("id") Long id) {
        return userAssembler.toListResource(roleService.getAllUsers(id));
    }

    //========================================角色与用户 end============================================

    //========================================角色与资源 begin============================================

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{id}/resources", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "getResources", httpMethod = "GET", value = "查询角色所分配的资源列表")
    public final ListResource<ResourceResource> getResources(@ApiParam(value = "角色的主键id", required = true)
                                                             @PathVariable("id") Long id) {
        return resourceAssembler.toListResource(roleService.getResources(id));
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "/{id}/resource", method = RequestMethod.POST,
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE},
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "addRoleResource", httpMethod = "POST", value = "给角色分配资源")
    public final int addRoleResource(@ApiParam(value = "角色的主键id", required = true)
                                     @PathVariable("id") Long roleId,
                                     @ApiParam(value = "资源标识", required = true)
                                     @RequestParam("resourceIds") List<Long> resourceIds) {

        if (resourceIds.isEmpty()) {
            throw new InvalidArgumentException("resourceIds不能为空");
        }
        return resourceService.addRoleResource(roleId, resourceIds);
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @RequestMapping(value = "/{id}/resource", method = RequestMethod.DELETE,
            //consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE},
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(notes = "deleteRoleResource", httpMethod = "DELETE", value = "删除角色拥有的资源")
    public final int deleteRoleResource(@ApiParam(value = "角色的主键id", required = true)
                                        @PathVariable("id") Long roleId,
                                        @ApiParam(value = "资源标识", required = true)
                                        @RequestParam("resourceIds") List<Long> resourceIds) {

        if (resourceIds.isEmpty()) {
            throw new InvalidArgumentException("resourceIds不能为空");
        }
        return resourceService.deleteRoleResource(roleId, resourceIds);
    }
    //========================================角色与资源 end============================================
}
